import 'dart:collection';
import 'dart:convert';
import 'dart:io';

//import 'package:device_information/device_information.dart';
//import 'package:device_info_plus/device_info_plus.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart';
import 'package:ecy_app_flutter/EcyRouter.dart';
import 'package:ecy_app_flutter/ecycommon/utils/EcyLogger.dart';
import 'package:ecy_app_flutter/ecycommon/utils/EcyUserUtil.dart';
import 'package:ecy_app_flutter/user/model/EcyUserModel.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';

import '../constant/EcyEventConsnt.dart';
import '../constant/constant.dart';
import '../model/EcyApiCommonResponse.dart';
import 'EcyEventBus.dart';
import 'RoutesGlobalKey.dart';

///网络请求类
class EcyRequestbasemanager {
  factory EcyRequestbasemanager() => _instance;
  static late final EcyRequestbasemanager _instance =
      EcyRequestbasemanager._internal();

  EcyRequestbasemanager._internal() {
    EcyLogger.log("EcyRequestbasemanager init");
    EcyEventBus().on(EcyEventConst.kHttpConnected, (arg) {
      hasConnection = true;
    });
  }
  late bool hasConnection = true;

  /// 初始化请求
  Dio _initDio() {
    final options = BaseOptions(
        contentType: 'application/json',
        baseUrl: Constant.API_BASE_URL,
        // /login/getDeviceMobile
        connectTimeout: const Duration(seconds: 10),
        receiveTimeout: const Duration(seconds: 10),
        headers: {
          "X-Api-Version": "1.0",
          "X-Language": "zh_CN",
        });
    final dio = Dio(options); // With default `Options`.
    dio.interceptors.add(
      InterceptorsWrapper(
        onRequest:
            (RequestOptions options, RequestInterceptorHandler handler) async {
          EcyUserModel? userModel = await EcyUserUtil.getLoginedUserInfo();
          if (userModel != null) {
            options.headers["Authorization"] = userModel.token;
          }
          if (options.method == 'POST' ||
              options.method == 'post' ||
              options.method == 'PUT' ||
              options.method == 'DELETE') {
            EcyLogger.log('${DateTime.now().toLocal()}-->' +
                options.method +
                '-->${options.baseUrl}${options.path}' +
                "--->options.headers:" +
                options.headers.toString() +
                "--->data:" +
                options.data.toString());
          } else {
            EcyLogger.log('${DateTime.now().toLocal()}-->' +
                options.method +
                '-->${options.baseUrl}${options.path}' +
                "--->options.headers:" +
                options.headers.toString() +
                "--->queryParameters:" +
                options.queryParameters.toString());
          }

          return handler.next(options);
        },
        onResponse: (Response response, ResponseInterceptorHandler handler) {
          print(dio.options);
          EcyLogger.log(response);
          // 检查响应状态码
          var commonResponse =
              EcyApiCommonResponse.fromJson(response.data, (response) => json);
          if (commonResponse.code == 401) {
            // TOKEN失效或用户未授权，则重定向到登录页面
            EcyUserUtil.clearUserInfo();
            EcyEventBus().emit(EcyEventConst.kLogout);
            RoutesGlobalKey.navigatorKey.currentState?.pushNamed(
                EcyRouter.passwordLoginPage,
                arguments: {EcyRouter.kTargetUrl: ""});
            EasyLoading.showToast("登录信息已失效，请重新登录",
                duration: const Duration(seconds: 1));
            return handler.resolve(response);
          }
          return handler.next(response);
        },
        onError: (DioException error, ErrorInterceptorHandler handler) {
          EcyLogger.error(error);
          EasyLoading.dismiss();
          _handleError(error);
          return handler.next(error);
        },
      ),
    );
    return dio;
  }

  Dio _initDio2(Map<String, dynamic> headers) {
    final options = BaseOptions(
        contentType: 'application/json',
        baseUrl: Constant.API_BASE_URL,
        // /login/getDeviceMobile
        connectTimeout: const Duration(seconds: 10),
        receiveTimeout: const Duration(seconds: 10),
        headers: {"X-Api-Version": "1.0", "X-Language": "zh_CN", ...headers});
    final dio = Dio(options); // With default `Options`.
    dio.interceptors.add(
      InterceptorsWrapper(
        onRequest:
            (RequestOptions options, RequestInterceptorHandler handler) async {
          // hasConnection = false;
          // try {
          //   final result =
          //       await InternetAddress.lookup("https://www.goodsqi.com");
          //   if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
          //     hasConnection = true;
          //   }
          // } catch (e) {
          //   hasConnection = false;
          // }
          // if (!hasConnection) {
          //   EasyLoading.showToast("网络连接失败，请检查网络",
          //       duration: const Duration(seconds: 10));
          //   return;
          // }
          // final List<ConnectivityResult> connectivityResult = await (Connectivity().checkConnectivity());
          // if (connectivityResult.contains(ConnectivityResult.none)) {
          //   EasyLoading.showToast("网络连接失败，请检查网络");
          //   return;
          // }
          EcyUserModel? userModel = await EcyUserUtil.getLoginedUserInfo();
          if (userModel != null) {
            options.headers["Authorization"] = userModel.token;
          }
          if (options.method == 'POST' ||
              options.method == 'post' ||
              options.method == 'PUT') {
            EcyLogger.log('${DateTime.now().toLocal()}-->' +
                options.method +
                '-->${options.baseUrl}${options.path}' +
                "--->options.headers:" +
                options.headers.toString() +
                "--->data:" +
                options.data.toString());
          } else {
            EcyLogger.log('${DateTime.now().toLocal()}-->' +
                options.method +
                '-->${options.baseUrl}${options.path}' +
                "--->options.headers:" +
                options.headers.toString() +
                "--->queryParameters:" +
                options.queryParameters.toString());
          }

          return handler.next(options);
        },
        onResponse: (Response response, ResponseInterceptorHandler handler) {
          EcyLogger.log(response);
          // 检查响应状态码
          var commonResponse =
              EcyApiCommonResponse.fromJson(response.data, (response) => json);
          if (commonResponse.code == 401) {
            // TOKEN失效或用户未授权，则重定向到登录页面
            EcyUserUtil.clearUserInfo();
            EcyEventBus().emit(EcyEventConst.kLogout);
            RoutesGlobalKey.navigatorKey.currentState
                ?.pushNamed(EcyRouter.passwordLoginPage);
            EasyLoading.showToast("登录信息已失效，请重新登录",
                duration: const Duration(seconds: 1));
            return handler.resolve(response);
          }
          return handler.next(response);
        },
        onError: (DioException error, ErrorInterceptorHandler handler) {
          EcyLogger.error(error);
          EasyLoading.dismiss();
          _handleError(error);
          return handler.next(error);
        },
      ),
    );
    return dio;
  }

  _handleError(DioException error) {
    if (error.response != null) {
      var response = error.response;
      if (response?.statusCode == 401) {
        // 触发TOKEN过期事件
        // 跳转登录页面并清空栈
        RoutesGlobalKey.navigatorKey.currentState?.pushNamed("/login");
      }
      if (response?.statusCode == 404) {}
    }
  }

  Future<Map<String, dynamic>> post(String url, Object? body) async {
    final response =
        await _initDio().post(url, data: body).catchError((onError) {
      return {"code": 1, "result": null};
    });
    return response.data;
  }

  Future<Map<String, dynamic>> get(
      String url, Map<String, dynamic> queryParameters, [dynamic body]) async {
    // final Map<String, dynamic> baseParas = await getBaseParas(body);
    final response =
        await _initDio().get(url, queryParameters: queryParameters, data: body).catchError((onError) {
      return null;
    });
    return response.data;
  }

  Future<Map<String, dynamic>> put(String url, Object? body) async {
    // final Map<String, dynamic> baseParas = await getBaseParas(body);
    final response =
        await _initDio().put(url, data: body).catchError((onError) {
      return null;
    });
    return response.data;
  }

  Future<Map<String, dynamic>> delete(String urlPath, Object? body, [dynamic? queryParameters]) async {
    // final Map<String, dynamic> baseParas = await getBaseParas(body);
    final response =
        await _initDio().delete(urlPath, data: body, queryParameters: queryParameters).catchError((onError) {
      return null;
    });
    return response.data;
  }

  Future<Map<String, dynamic>> postWithHeader(
      Map<String, dynamic> headers, String url, Object? body) async {
    final response =
        await _initDio2(headers).post(url, data: body).catchError((onError) {
      return {"code": 1, "result": null};
    });
    return response.data;
  }

  Future<Map<String, dynamic>> getBaseParas(Map<String, dynamic> body) async {
    try {
      // final deviceInfo = DeviceInfoPlugin();
      //var imeiNo = await DeviceInformation.deviceIMEINumber;
      //这边修改过需要用到的话要改一下
      //    var imeiNo = await deviceInfo.androidInfo;
      if (body != null) {
        //  body["imei"] = imeiNo;
        //    var platformVersion = await DeviceInformation.platformVersion;
        //    var modelName = await DeviceInformation.deviceModel;
        //  var deviceName = await DeviceInformation.deviceName;
        // var productName = await DeviceInformation.productName;
        return body;
      } else {
        return ({"imei": ""});
      }
    } on PlatformException {
      return body;
    }
  }
}
